<template>
  <div id='xterm'></div>
</template>

<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref } from 'vue'
import 'xterm/css/xterm.css'
import { Terminal } from 'xterm';
import { FitAddon } from "xterm-addon-fit";
import { io, Socket } from "socket.io-client";
import chalk from 'chalk'
const wsInstance = ref<Socket>()
const xtermInstance = ref<Terminal>()

onMounted(() => {
  setTimeout(() => {
    initTerm()
  }, 200);
})

onBeforeUnmount(() => {
  wsInstance.value?.close()
  xtermInstance.value?.dispose()
})

//初始化当前系统环境，返回终端的 pid，标识当前终端的唯一性
const initSysEnv = async () =>
  await fetch("/api/terminal", {
    method: 'post'
  })
    .then((res) => res.json())
    .then((res) => res)
    .catch((err) => {
      throw new Error(err);
    });

const initSocket = (pid: string) => {
  const socket = io('ws://127.0.0.1:8899', {
    transports: ["websocket"],
    query: {
      pid
    }
  });
  console.log('socket', socket)
  wsInstance.value = socket
  bindEvent(socket)
  return socket
}

const initTerm = async () => {
  const element = document.getElementById('xterm')
  if (!element) return
  // 设置了cols或者fitAddon.fit(); 当一行字符超过80个过会替换现在的内容，否则换行
  const term = new Terminal({
    cursorBlink: true, // 关闭闪烁
    cursorStyle: 'underline', // 光标样式
    scrollback: 100, //当行的滚动超过初始值时保留行视窗，越大回滚能看到的内容越多
    fontFamily: 'Menlo, Monaco, "Courier New", monospace',
    fontWeight: 400,
    fontSize: 13,
    rows: 50,
    cols: 130
  })
  // term.writeln('需要启动后端服务: ' + chalk.red('backend'))
  const fitAddon = new FitAddon()
  term.loadAddon(fitAddon)
  fitAddon.fit()
  const pid = await initSysEnv()
  const socket = initSocket(pid)

  // const attachAddon = new AttachAddon(socket.io)
  // term.loadAddon(attachAddon)
  term.open(element)
  term.focus()
  term.onData((data: string) => {
    // console.log('输入的命令', data)
    wsInstance.value?.emit('message', data)
  })
  xtermInstance.value = term
}


const bindEvent = (socket: Socket) => {
  socket.on('message', function (data) {
    // console.log('data', data)
    // 接收推送的消息
    xtermInstance.value!.write(data);
  });
}

</script>

<style scoped lang="scss">
#xterm {
  width: 100%;
  height: 100%;
}
</style>
